package MyComponent// ActionScript file
{
	import MyComponent.Events.MyScrollEvent;
	
	import fl.core.InvalidationType;
	import fl.core.UIComponent;
	import fl.events.ComponentEvent;
	
	import flash.events.MouseEvent;

	public class MyScrollBar extends UIComponent
	{
		private var _pageSize:Number=0;
		private var _pageTotalSize:Number=0;
		private var _thumbHeightLocked:Boolean=false;
		private var _scrollPosition:Number=0;
		private var _maxScrollPosition:Number=0;
		private var _lineScrollPosition:Number=1;
		private var _inDrag:Boolean=false;
		private var _mousePosition:Number;
		private var _skinsType:String;
		
		private var _thumb:MyButton;
		private var _track:MyButton;
		private var _upArrow:MyButton;
		private var _downArrow:MyButton;
		private static var defaultStyles:Object = {thumbSkinsType:"MyScrollBar_default_thumbSkins",trackSkinsType:"MyScrollBar_default_trackSkins",upArrowSkinsType:"MyScrollBar_default_upArrowSkins",downArrowSkinsType:"MyScrollBar_default_downArrowSkins"};
		
		public function MyScrollBar():void
		{
			super();
			this.setStyles();
			this.addListener();
		}
		
		public static function getStyleDefinition():Object
		{
			return defaultStyles;
		}
		
		private function addListener():void
		{
			this.upArrow.addEventListener(ComponentEvent.BUTTON_DOWN,pressButtonHandler,false,0,true);
			this.downArrow.addEventListener(ComponentEvent.BUTTON_DOWN,pressButtonHandler,false,0,true);
			this.thumb.addEventListener(ComponentEvent.BUTTON_DOWN,pressButtonHandler,false,0,true);
			this.track.addEventListener(ComponentEvent.BUTTON_DOWN,pressButtonHandler,false,0,true);
		}
		
		private function pressButtonHandler(e:ComponentEvent):void
		{
			e.stopImmediatePropagation();
			if(e.currentTarget==this.upArrow)
			{
				this.setScrollPosition(this.scrollPosition-this.lineScrollPosition);
			}
			else if(e.currentTarget==this.downArrow)
			{
				this.setScrollPosition(this.scrollPosition+this.lineScrollPosition);
			}
			else if(e.currentTarget==this.thumb)
			{
				this.inDrag=true;
				this.mousePosition=this.thumb.mouseY;
				this.mouseChildren=false;
				this.stage.addEventListener(MouseEvent.MOUSE_UP,releaseThumbHandler,false,0,true);
				this.stage.addEventListener(MouseEvent.MOUSE_MOVE,dragThumbHandler,false,0,true);
			}
			else if(e.currentTarget==this.track)
			{
				this.setScrollPosition(this.track.mouseY-this.thumb.height/2);
			}
		}
		
		private function setScrollPosition(newScrollPosition:Number,fireEvent:Boolean=true):void
		{
			if(newScrollPosition<0)
			{
				newScrollPosition=0;
			}
			else if(newScrollPosition>this.maxScrollPosition)
			{
				newScrollPosition=this.maxScrollPosition;
			}
			if(newScrollPosition==this.scrollPosition)return;
			this.scrollPosition=newScrollPosition;
			if(fireEvent)this.dispatchEvent(new MyScrollEvent(this.scrollPosition,this.maxScrollPosition));
			this.thumb.y=this.track.y+this.scrollPosition;
		}
		
		private function dragThumbHandler(e:MouseEvent):void
		{
			var positionChange:Number=this.thumb.mouseY-this.mousePosition;
			this.setScrollPosition(this.scrollPosition+positionChange);
			e.updateAfterEvent();
		}
		
		private function releaseThumbHandler(e:MouseEvent):void
		{
			this.inDrag=false;
			this.mouseChildren=true;
			this.stage.removeEventListener(MouseEvent.MOUSE_UP,releaseThumbHandler,false);
			this.stage.removeEventListener(MouseEvent.MOUSE_MOVE,dragThumbHandler,false);
		}
		
		override protected function configUI():void
		{
			super.configUI();
			
			this._track=new MyButton;
			this.track.move(0,15);
			this.addChild(this.track);
			
			this._thumb=new MyButton;
			this.thumb.setSize(15,15);
			this.thumb.move(0,15);
			this.addChild(this.thumb);
			
			this._downArrow=new MyButton;
			this.downArrow.setSize(15,15);
			this.addChild(this.downArrow);
			
			this._upArrow=new MyButton;
			this.upArrow.setSize(15,15);
			this.addChild(this.upArrow);
		}

		override protected function draw():void
		{
			if (this.isInvalid(InvalidationType.SIZE)) 
			{
				var h:Number = super.height;
				this.downArrow.move(0,Math.max(this.upArrow.height+12, h-this.downArrow.height));
				this.track.setSize(15,Math.max(12,h-this.upArrow.height-this.downArrow.height));
				this.updateThumb();
			}
			if (isInvalid(InvalidationType.STYLES,InvalidationType.STATE)) {
				setStyles();
			}
			this.childrenDrawNow();
			this.validate();
		}
		
		private function childrenDrawNow():void
		{
			this.downArrow.drawNow();
			this.upArrow.drawNow();
			this.thumb.drawNow();
			this.thumb.drawNow();
		}
		
		public function setStyles():void
		{
			this.thumb.skinsType=String(this.getStyleValue("thumbSkinsType"));
			this.track.skinsType=String(this.getStyleValue("trackSkinsType"));
			this.upArrow.skinsType=String(this.getStyleValue("upArrowSkinsType"));
			this.downArrow.skinsType=String(this.getStyleValue("downArrowSkinsType"));
		}
		
		private function updateThumb():void
		{
			var h:Number=12;
			if(this.pageTotalSize && !this.thumbHeightLocked)
			{
				h=this.track.height*(this.pageSize/this.pageTotalSize);
				if(h>this.track.height)
				{
					h=this.track.height;
				}
				else if(h<12)
				{
					h=12;
				}
			}
			this.thumb.height=h;
			this.maxScrollPosition=this.track.height-this.thumb.height;
			this.setScrollPosition(this.scrollPosition);
		}

		/*getter & setter*/
		public function get thumb():MyButton
		{
			return _thumb;
		}

		public function get track():MyButton
		{
			return _track;
		}

		public function get upArrow():MyButton
		{
			return _upArrow;
		}

		public function get downArrow():MyButton
		{
			return _downArrow;
		}

		public function get scrollPosition():Number
		{
			return _scrollPosition;
		}

		public function set scrollPosition(value:Number):void
		{
			_scrollPosition = value;
		}

		public function get maxScrollPosition():Number
		{
			return _maxScrollPosition;
		}

		public function set maxScrollPosition(value:Number):void
		{
			_maxScrollPosition = value;
		}

		public function get lineScrollPosition():Number
		{
			return _lineScrollPosition;
		}

		public function set lineScrollPosition(value:Number):void
		{
			_lineScrollPosition = value;
		}

		public function get inDrag():Boolean
		{
			return _inDrag;
		}

		public function set inDrag(value:Boolean):void
		{
			_inDrag = value;
		}

		public function get mousePosition():Number
		{
			return _mousePosition;
		}

		public function set mousePosition(value:Number):void
		{
			_mousePosition = value;
		}

		public function get pageSize():Number
		{
			return _pageSize;
		}

		public function set pageSize(value:Number):void
		{
			_pageSize = value;
			this.updateThumb();
		}

		public function get pageTotalSize():Number
		{
			return _pageTotalSize;
		}

		public function set pageTotalSize(value:Number):void
		{
			_pageTotalSize = value;
			this.updateThumb();
		}

		[Inspectable(defaultValue=false,type="Boolean")]
		public function get thumbHeightLocked():Boolean
		{
			return _thumbHeightLocked;
		}

		public function set thumbHeightLocked(value:Boolean):void
		{
			_thumbHeightLocked = value;
			this.updateThumb();
		}

		[Inspectable(defaultValue="MyScrollBar_default",type="String")]
		public function set skinsType(value:String):void
		{
			if(value==this.skinsType)return;
			var thumbSkinsStr:String=value+"_thumbSkins";
			var trackSkinsStr:String=value+"_trackSkins";
			var upArrowSkinsStr:String=value+"_upArrowSkins";
			var downArrowSkinsStr:String=value+"_downArrowSkins";
			this.setStyle("thumbSkinsType",thumbSkinsStr);
			this.setStyle("trackSkinsType",trackSkinsStr);
			this.setStyle("upArrowSkinsType",upArrowSkinsStr);
			this.setStyle("downArrowSkinsType",downArrowSkinsStr);
			this.invalidate(InvalidationType.STYLES);
			_skinsType = value;
		}
		
		public function get skinsType():String
		{
			return _skinsType;
		}


		
	}
}